package com.guoqi.oabridge

import android.net.Uri
import android.text.TextUtils
import com.alibaba.fastjson.JSON
import com.guoqi.oabridge.bridgeImpl.IBridge
import com.tencent.smtt.sdk.WebView
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.util.*

object JSBridge {
    private val exposedMethods = HashMap<String, HashMap<String, Method>>()

    fun register(exposedName: String, clazz: Class<out IBridge>) {
        if (!exposedMethods.containsKey(exposedName)) {
            try {
                exposedMethods[exposedName] = getAllMethod(clazz)
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }
    }

    @Throws(Exception::class)
    private fun getAllMethod(injectedCls: Class<*>): HashMap<String, Method> {
        val mMethodsMap = HashMap<String, Method>()
        val methods = injectedCls.declaredMethods
        for (method in methods) {
            val name: String = method.name
            if (method.modifiers != Modifier.PUBLIC or Modifier.STATIC || name == null) {
                continue
            }
            val parameters = method.parameterTypes
            if (null != parameters && parameters.size == 3) {
                //                if (parameters[0] == WebView.class && parameters[1] == JSONObject.class && parameters[2] == Callback.class) {
                mMethodsMap[name] = method
                //                }
            }
        }
        return mMethodsMap
    }


    fun callJava(webView: WebView?, uriString: String?): String? {
        var methodName = ""
        var className: String? = ""
        var param: String? = "{}"
        var port = ""
        if (!TextUtils.isEmpty(uriString) && uriString!!.startsWith("JSBridge")) {
            val uri = Uri.parse(uriString)
            className = uri.host
            param = uri.query
            if (param.isNullOrEmpty()){
                param = "{}"
            }
            port = uri.port.toString() + ""
            val path = uri.path
            if (!TextUtils.isEmpty(path)) {
                methodName = path!!.replace("/", "")
            }
        }


        if (exposedMethods.containsKey(className)) {
            val methodHashMap = exposedMethods[className]

            if (methodHashMap != null && methodHashMap.size != 0 && methodHashMap.containsKey(methodName)) {
                val method = methodHashMap[methodName]
                if (method != null) {
                    try {
                        method.invoke(null, webView, JSON.parseObject(param), Callback(webView!!, port))
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }

                }
            }
        }
        return null
    }
}